home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / DVIM72-Mac 1.9.6 / source / dvim72.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-14  |  14.0 KB  |  444 lines  |  [TEXT/R*ch]

  1. /* -*-C-*- dvim72.c */
  2. /*-->dvim72*/
  3. /**********************************************************************/
  4. /******************************* dvim72 *******************************/
  5. /**********************************************************************/
  6.  
  7. #include "dvihead.h"
  8.  
  9. #include "gendefs.h"
  10.  
  11. #include "m72.h"
  12.  
  13.  
  14. #if OS_THINKC
  15. #include "mac-specific.h"
  16. #include "PrintTraps.h"
  17. #include "sillymalloc.h"
  18. #endif
  19.  
  20. /* #include "main.h" */
  21. /**********************************************************************/
  22. /****************************** main.h *******************************/
  23. /**********************************************************************/
  24.  
  25. /**********************************************************************/
  26. /***********************  External Definitions  ***********************/
  27. /**********************************************************************/
  28.  
  29. #if    KCC_20
  30. #include <file.h>
  31. #endif /* KCC_20 */
  32.  
  33. #if    PCC_20                /* this stuff MUST be first */
  34.  
  35. #undef tops20                /* to keep definitions alive */
  36. #include <ioctl.h>            /* PCC-20 does not have this in */
  37.                     /* the others */
  38. #include <file.h>            /* need for f20open flags and */
  39.                     /* JSYS stuff */
  40. #define tops20  1            /* define for tops-20 */
  41. #endif /* PCC_20 */
  42.  
  43. #include "commands.h"
  44. #include <ctype.h>
  45. #include <math.h>
  46.  
  47. #if    OS_UNIX
  48. #if    BSD42
  49.  
  50. #include <sys/ioctl.h>            /* need for DVISPOOL in dviterm.h */
  51.  
  52. #ifndef _NFILE
  53. /* VAX VMS, NMTCC, PCC-20, and HPUX have _NFILE in stdio.h.  V7 called
  54. it NFILE, and Posix calls it OPEN_MAX.  KCC-20 calls it SYS_OPEN.  VAX
  55. 4.3BSD and Gould UTX/32 don't define _NFILE in stdio.h; they use
  56. NOFILE from sys/param.h.  Sigh.... */
  57. #include <sys/param.h>
  58. #ifdef NOFILE
  59. #define _NFILE NOFILE            /* need for gblvars.h */
  60. #else
  61. #define _NFILE MAXOPEN            /* use our font limit value */
  62. #endif
  63. #endif
  64.  
  65. #endif /* BSD42 */
  66. #endif /* OS_UNIX */
  67.  
  68. #include "gblprocs.h"
  69.  
  70. #include "gblvars.h"
  71.  
  72. #if    OS_ATARI
  73. long _stksize = 20000L; /* make the stack a bit larger than 2KB */
  74.                         /* number must be even                  */
  75. #endif /* OS_ATARI */
  76.  
  77.  
  78. /**********************************************************************/
  79. /*******************************  main  *******************************/
  80. /**********************************************************************/
  81. /**********************************************************************/
  82. /**********************************************************************/
  83. /**********************************************************************/
  84.  
  85.  
  86. /* #include "abortrun.h" */
  87. /* #include "actfact.h" */
  88. /* #include "alldone.h" */
  89. /* #include "chargf.h" */
  90. /* #include "charpk.h" */
  91. /* #include "charpxl.h" */
  92. /* #include "clrbmap.h" */
  93.  
  94. /* #include "clrrow.h" */
  95. /* #include "dbgopen.h" */
  96.  
  97. /*-->devinit*/
  98. /**********************************************************************/
  99. /****************************** devinit *******************************/
  100. /**********************************************************************/
  101. #if OS_THINKC
  102. #else /* not OS_THINKC */
  103. void
  104. devinit(argc,argv)        /* initialize device */
  105. int argc;
  106. char *argv[];
  107. {
  108.     (void)getbmap();
  109.     if (runlengthcode && !quiet)
  110.     {
  111.     (void)printf("[Run-length encoding of output file]");
  112.     printf("\n");
  113.     }
  114. }
  115. #endif  /* OS_THINKC */
  116.  
  117. /*-->devterm*/
  118. /**********************************************************************/
  119. /****************************** devterm *******************************/
  120. /**********************************************************************/
  121. /* Replaced by Close_printer */
  122.  
  123. /**********************************************************************/
  124. /****************************** openfont ******************************/
  125. /**********************************************************************/
  126.  
  127. void
  128. openfont(fontname)
  129. char *fontname;
  130.  
  131. /***********************************************************************
  132.     The original version of this DVI driver reopened the font file  each
  133.     time the font changed, resulting in an enormous number of relatively
  134.     expensive file  openings.    This version  keeps  a cache  of  up  to
  135.     MAXOPEN open files,  so that when  a font change  is made, the  file
  136.     pointer, fontfp, can  usually be  updated from the  cache.  When the
  137.     file is not found in  the cache, it must  be opened.  In this  case,
  138.     the next empty slot  in the cache  is assigned, or  if the cache  is
  139.     full, the least used font file is closed and its slot reassigned for
  140.     the new file.  Identification of the least used file is based on the
  141.     counts of the number  of times each file  has been "opened" by  this
  142.     routine.  On return, the file pointer is always repositioned to  the
  143.     beginning of the file.
  144.  
  145.     If the first open attempt  fails, an attempt will  be made to use  a
  146.     substitute font, then neighboring magnifications (with the same font
  147.     name), or substitutes for them.
  148. ***********************************************************************/
  149.  
  150. {
  151.     register INT16 i,j,k;    /* loop indices */
  152.     INT16 current;
  153.     INT16 least_used;
  154.     INT16 maxopen = MAXOPEN;
  155.    float resfact = RESOLUTION / 200.0;
  156.  
  157.  
  158.     struct font_entry *tfontptr;
  159.     char subfont[MAXFNAME];
  160.     int submag;
  161.     char* filelist[MAXFORMATS];    /* pointers to templist[][] */
  162.     char templist[MAXFORMATS][MAXFNAME];
  163.  
  164. #if    VIRTUAL_FONTS
  165.     struct stat statbuf;        /* so fstat() can get file size */
  166.     char *p;
  167. #endif
  168.  
  169.     if ((pfontptr != (struct font_entry *)NULL) && (pfontptr == fontptr))
  170.     return;            /* we need not have been called */
  171.  
  172.     for (j = 0; j < MAXFORMATS; ++j)    /* initialize fontlist pointers */
  173.     filelist[j] = &templist[j][0];
  174.  
  175.     for (current = 1;
  176.         (current <= nopen) &&
  177.         (font_files[current].font_id != fontptr->font_file_id);
  178.         ++current)
  179.     ;            /* try to find file in open list */
  180.  
  181.     if (current <= nopen)    /* file already open, lookup its id */
  182.         fontfp = font_files[current].font_id;
  183.     else
  184.     {
  185.     /***************************************************************
  186.     The file was  not in list  of open  files.  If the  list is  not
  187.     full, add it to  the list; otherwise  close the least-used  file
  188.     and remove it from the font_entry containing it.  Finally,  open
  189.     the file, or its closest  neighbor in the magnification  family.
  190.     A warning is issued  if no file can  be opened.  The caller  can
  191.     then proceed with zero font metrics if desired.
  192.     ***************************************************************/
  193.  
  194.  
  195.     if (nopen < maxopen)    /* just add it to list */
  196.         current = ++nopen;
  197.     else            /* list full -- find least used file, */
  198.     {            /* close it, and reuse slot for new file */
  199.         least_used = 1;
  200.         for (i = 2; i <= maxopen; ++i)
  201.             if (font_files[least_used].use_count >
  202.                     font_files[i].use_count)
  203.                 least_used = i;
  204.  
  205.         fontfp = font_files[least_used].font_id;
  206.         tfontptr = hfontptr;
  207.         while (tfontptr != (struct font_entry*)NULL)
  208.         {            /* remove file pointer from its font_entry */
  209.             if (tfontptr->font_file_id == fontfp)
  210.             {
  211.                 tfontptr->font_file_id = (FILE*)NULL;
  212.                 break;
  213.             }
  214.             tfontptr = tfontptr->next;
  215.         }
  216.  
  217. #if    VIRTUAL_FONTS
  218.         if (virt_font && (fontfp != (FILE*)NULL))
  219.             (void)virtfree(fontfp);
  220. #endif
  221.  
  222.         (void)fclose(fontfp);
  223.         fontfp = (FILE*)NULL;
  224.         current = least_used;
  225.     }
  226.     (void)actfact_res(fontptr->font_mag);    /* Get global mag_index */
  227.  
  228.     fontfp = (FILE*)NULL;
  229.  
  230.     /***************************************************************
  231.     Try the requested font, then any substitute font, then for  each
  232.     neighboring magnification  from  nearest to  furthest,  try  the
  233.     requested font, and then any substitute font.
  234.     ***************************************************************/
  235.  
  236.     for (k = 0; (fontfp == (FILE*)NULL) && (k < MAGTABSIZE); ++k)
  237.     {                /* loop over mag family */
  238.         for (i = -k; (fontfp == (FILE*)NULL) && (i <= k); i += MAX(1,k+k))
  239.         {                /* try smaller, then larger */
  240.             if (IN(0,mag_index+i,MAGTABSIZE-1))
  241.             {
  242.                 (void)fontfile(filelist, ((fontptr->a==0)?fontpath:""),
  243.                 fontname, (int)MAGSIZE(mag_table[mag_index+i]*resfact));
  244.                 for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
  245.                 {
  246.                     fontfp = FOPEN(filelist[j],RB_OPEN);
  247.                     DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
  248.                     if (fontfp != (FILE *)NULL)
  249.                     {
  250.                         strcpy(fontptr->name,filelist[j]);
  251.                         break;
  252.                     }
  253.                     if (User_wants_out())
  254.                         break;
  255.                 }
  256.                 if ((k > 0) && (fontfp != (FILE*)NULL))
  257.                 {
  258.                 (void)sprintf(message,
  259.                     "Font file [%s [mag %d]] could not be opened.\n"
  260.                     "---using nearest neighbor [%s [mag %d]] instead.",
  261.                     fontname,(int)MAGSIZE(mag_table[mag_index]*resfact),
  262.                     fontptr->name,
  263.                     (int)MAGSIZE(mag_table[mag_index+i]*resfact));
  264.                 (void)warning(message);
  265.                 }
  266.     
  267.                 if ((fontfp == (FILE*)NULL) && fontsub(subfont,&submag,
  268.                 fontname,(int)MAGSIZE(mag_table[mag_index+i]*resfact)))
  269.                 {
  270.                     (void)fontfile(filelist,((fontptr->a==0)?fontpath:""),
  271.                         subfont,(submag ? submag :
  272.                         (int)MAGSIZE(mag_table[mag_index+i]*resfact)));
  273.                     for (j = 0; (j < MAXFORMATS) && *filelist[j]; ++j)
  274.                     {
  275.                         fontfp = FOPEN(filelist[j],RB_OPEN);
  276.                         DEBUG_OPEN(fontfp,filelist[j],RB_OPEN);
  277.                         if (fontfp != (FILE *)NULL)
  278.                         {
  279.                             strcpy(fontptr->name,filelist[j]);
  280.                             break;
  281.                         }
  282.                         if (User_wants_out())
  283.                             break;
  284.                     }
  285.         
  286.                     if (fontfp != (FILE*)NULL)
  287.                     {
  288.                         (void)sprintf(message,
  289.                         "Substituting font file [%s [mag %d]] "
  290.                         "by [%s [mag %d]]",
  291.                         fontname, submag,
  292.                         /* (int)MAGSIZE(mag_table[mag_index]*resfact), */
  293.                         fontptr->name,
  294.                         (int)MAGSIZE(mag_table[mag_index+i]*resfact));
  295.                         (void)warning(message);
  296.                     }
  297.                 }
  298.             }
  299.             if (g_abort_dvi)
  300.                 break;
  301.         } /* end for (i) -- loop over smaller and larger neighbors  */
  302.         if (g_abort_dvi)
  303.             break;
  304.     } /* end for (k) -- loop over mag family */
  305.  
  306.     if (fontfp == (FILE*)NULL)
  307.     {
  308.         --nopen;            /* don't count this failed open */
  309.         (void)sprintf(message,"Font file [%s [mag %d]] could not be \
  310. opened; %d font files are open\n\
  311. Proceeding with zero size characters for this font",
  312.         fontname,(int)MAGSIZE(mag_table[mag_index]*resfact),nopen);
  313.         (void)warning(message);
  314.     }
  315.  
  316.     font_files[current].font_id = fontfp;
  317.     font_files[current].use_count = 0;
  318.  
  319. #if    VIRTUAL_FONTS
  320.     /*
  321.     ****************************************************************
  322.     This code  is implementation-dependent.   On many  C  compilers,
  323.     FILE points to a struct of the form
  324.  
  325.     struct    _iobuf {
  326.         char    *_ptr;    // pointer to next available char
  327.         int    _cnt;    // number of chars left in buffer
  328.         char    *_base;    // pointer to start of buffer
  329.         int    _flag;    // assorted flags
  330.         int    _file;    // file number handle
  331.         }
  332.  
  333.     To implement virtual fonts,  we save the  pointers in a  private
  334.     global array, get the file size from fstat(), malloc() a  buffer
  335.     for it, read the entire file in, and replace the pointers in the
  336.     FILE variable with ones  for  the  new buffer.  Just before  the
  337.     file is  closed, the space is  freed  and the   old pointers are
  338.     restored.   Although many C implementations use  malloc() to get
  339.     the buffer  space  in the  first place, which  would  make  this
  340.     saving unnecessary, not all do; see  the implementation given in
  341.     Kernighan and Ritchie "The C Programming Language", p. 168.
  342.  
  343.     In  implementing   this   code   on   any   new   machine,   the
  344.     implementations of fread(), read(), fseek(), and rewind() should
  345.     be checked to  choose the  most efficient one  (e.g. one  system
  346.     call for entire file  read, and no  double buffering), and  make
  347.     sure that  fseek() and  rewind()  do not  unnecessarily  discard
  348.     input buffer  contents.  fseek()  and  rewind() are  defined  in
  349.     terms of macros FSEEK() and REWIND() in machdefs.h to facilitate
  350.     replacement.
  351.     ****************************************************************
  352.     */
  353.     if (virt_font)
  354.     {
  355.         virt_save[fileno(fontfp)].base = (char *)NULL;
  356.         (void)fstat(fileno(fontfp),&statbuf);    /* get file size */
  357.         p = (char *)MALLOC((int)statbuf.st_size);    /* get file buffer */
  358.         if (p != (char *)NULL)
  359.         {
  360.         if (READ(fileno(fontfp),p,(int)statbuf.st_size)
  361.              == (int)statbuf.st_size)
  362.         {            /* read successful */
  363.             virt_save[fileno(fontfp)].ptr = FILE_PTR(fontfp);
  364.             virt_save[fileno(fontfp)].cnt = FILE_CNT(fontfp);
  365.             virt_save[fileno(fontfp)].base = FILE_BASE(fontfp);
  366.             FILE_PTR(fontfp) = p;
  367.             FILE_BASE(fontfp) = p;
  368.             FILE_CNT(fontfp) = (int)statbuf.st_size;
  369.         }
  370.         else            /* failure */
  371.         {
  372.             (void)REWIND(fontfp);
  373.             (void)free(p);    /* free dynamic buffer */
  374.         }
  375.         }
  376.         if (DBGOPT(DBG_FONT_CACHE))
  377.         {
  378.             (void)printf("\nopenfont(): Font file %d [%s] ",
  379.             (int)fileno(fontfp),fontptr->name);
  380.             if (p == (char *)NULL)
  381.             (void)printf(
  382.             "cannot callocate buffer for entire file\n");
  383.         else
  384.             (void)printf(
  385.             "buffer length 0x%x\told buffer at 0x%lx\t\
  386. new buffer at 0x%lx\n",
  387.             (int)statbuf.st_size,
  388.             (long)virt_save[fileno(fontfp)].base,
  389.             (long)FILE_BASE(fontfp));
  390.         }
  391.     }
  392. #endif
  393.  
  394.     } /* end if (file is in open list) */
  395.  
  396.     pfontptr = fontptr;            /* make previous = current font */
  397.     fontptr->font_file_id = fontfp;    /* set file identifier */
  398.     font_files[current].use_count++;    /* update reference count */
  399. }
  400.  
  401. #if    VIRTUAL_FONTS
  402. void
  403. virtfree(fp)                /* free buffer space before close */
  404. FILE *fp;
  405. {
  406.     if (virt_font && (fp != (FILE*)NULL) &&
  407.     (virt_save[fileno(fp)].base != (char *)NULL))
  408.     {
  409.     (void)fflush(fp);
  410.     (void)free(FILE_BASE(fp));
  411.     FILE_PTR(fp) = virt_save[fileno(fp)].ptr;
  412.     FILE_CNT(fp) = virt_save[fileno(fp)].cnt;
  413.     FILE_BASE(fp) = virt_save[fileno(fp)].base;
  414.     virt_save[fileno(fp)].base = (char *)NULL;
  415.     }
  416. }
  417. #endif
  418.  
  419. /* #include "option.h" */
  420. /* #include "outrow.h" */
  421. /* #include "prtpage.h" */
  422. /* #include "readfont.h" */
  423. /* #include "readgf.h" */
  424. /* #include "readpk.h" */
  425. /* #include "readpost.h" */
  426. /* #include "readpxl.h" */
  427. /* #include "reldfont.h" */
  428. /* #include "rulepxl.h" */
  429. /* #include "setchar.h" */
  430. /* #include "setfntnm.h" */
  431. /* #include "setrule.h" */
  432. /* #include "signex.h" */
  433. /* #include "skgfspec.h" */
  434. /* #include "skipfont.h" */
  435. /* #include "skpkspec.h" */
  436. /* #include "special.h" */
  437. /* #include "strchr.h" */
  438. /* #include "strcm2.h" */
  439. /* #include "strid2.h" */
  440. /* #include "strrchr.h" */
  441. /* #include "tctos.h" */
  442. /* #include "usage.h" */
  443. /* #include "warning.h" */
  444.